# Confidentiality Notice: Please note that you are accessing a confidential
# proprietary script which is owned by Synopsys, Inc. and considered part of
# the PrimeTime software. Access is only permitted under the terms of the
# International Symposium on Physical Design 2012 Contest PrimeTime
# Non-Disclosure Agreement.

proc HSTA_read_design {} {
    #set lib_name "tcbn45gsbwpwc"
    #set search_path [list . "/users/lmin/TSMC_LIB_2013/tcbn45gsbwp_120a/"]
    #set link_library [list $lib_name]
    puts $::env(HSTA_BENCHMARK_DIR)
    puts "hehe"
    #if { 0 == [read_lib /users/lmin/TSMC_LIB_2013/tcbn45gsbwp_120a/$lib_name.lib] } {
    #    return "err"
    #} else {
    #    puts "-Info-: Read Tech library"
    #}
    read_db /home/lmin/hybrid-sta/TSMC_LIB_2013/NLDM/tcbn45gsbwp_120a/tcbn45gsbwptc.db
    remove_design -all
    list_designs -all 
    if { 0 == [read_verilog $::env(HSTA_BENCHMARK_DIR)/$::env(HSTA_BENCHMARK).v] } {
        return "err"
    } else {
        puts "-Info-: Read verilog"
    }
    list_designs -all 
    get_ports blif_reset_clk
    set_design_top $::env(HSTA_BENCHMARK) 
    current_design "$::env(HSTA_BENCHMARK)"
    link_design "$::env(HSTA_BENCHMARK)"
    
    if { 0 == [read_sdc $::env(HSTA_BENCHMARK_DIR)/$::env(HSTA_BENCHMARK).sdc] }{ 
        return "err"        
    } else {
        puts "-Info-: Read SDC"
    }
    if { 0 == [read_parasitics $::env(HSTA_BENCHMARK_DIR)/$::env(HSTA_BENCHMARK).spef] } {
        return "err"
    } else {
        puts "-Info-: Read SPEF"
    }

    return ""
}


proc run_timing {} {
    set desName [get_attribute [get_design] full_name]
    
    if {$desName == ""} {
        puts "Error: Design not loaded!"
        return "err"
    }
    
    set timingFileName "$::env(HSTA_BENCHMARK_DIR)/$desName.timing"
    file delete -force $timingFileName
    
    set ceffFileName "$::env(HSTA_BENCHMARK_DIR)/$desName.ceff"
    file delete -force $ceffFileName
    
    
    #################################################
    ######## Update timing                       ####
    #################################################    

    
    #set ::rc_cache_min_max_rise_fall_ceff true
    set ::timing_save_pin_arrival_and_slack true
    update_timing

    #printvar rc_cache_min_max_rise_fall_ceff
    
    #################################################
    ######## Write timing info                   ####
    #################################################    
    
    exec touch $timingFileName
    exec touch $ceffFileName
    
    if {[catch {set ofp [open $timingFileName w]}]} {
        puts "Error: Cannot open file $timingFileName for write"
        return "err"
    }
    
    if {[catch {set cofp [open $ceffFileName w]}]} {
        puts "Error: Cannot open file $ceffFileName for write"
        return "err"
    }
    
    puts $ofp "# pin timing\n"
    puts $cofp "# pin ceff\n"
    foreach_in_collection pin [get_pins *] {
        if { [get_attribute $pin is_clock_pin] } {
            # don't print timing for clock pins
            continue
        }
        set pinName [get_attribute $pin full_name]
        set fanoutLoad [get_attribute $pin fanout_load]
        #set minriseCeff [get_attribute $pin cached_ceff_min_rise]
        #set maxriseCeff [get_attribute $pin cached_ceff_max_rise]
        #set minfallCeff [get_attribute $pin cached_ceff_min_fall]
        #set maxfallCeff [get_attribute $pin cached_ceff_max_fall]
        #set maxCeff [get_attribute $pin ceff_params_max]
        #set minCeff [get_attribute $pin ceff_params_min]
        
        set riseArrival [get_attribute $pin max_rise_arrival]
        set fallArrival [get_attribute $pin max_fall_arrival]
        set riseSlack [get_attribute $pin max_rise_slack]
        set fallSlack [get_attribute $pin max_fall_slack]
        set riseTransition [get_attribute $pin actual_rise_transition_max]
        set fallTransition [get_attribute $pin actual_fall_transition_max]
        
        #puts $ofp "$pinName $riseSlack $fallSlack $riseTransition $fallTransition"
        puts $ofp "$pinName $riseArrival $fallArrival $riseSlack $fallSlack $riseTransition $fallTransition"
        #puts $cofp "$pinName $fanoutLoad $minriseCeff $maxriseCeff $minfallCeff maxfallCeff"
        #puts $cofp "$pinName $fanoutLoad $minCeff $maxCeff"
    }
    
    puts $ofp "\n# port timing\n"
    foreach_in_collection port [get_ports *] {
        set portName [get_attribute $port full_name]
        if { "blif_clk_net" == $portName } {
            # Clock ports will always use clk as the single clock port
            continue;
        }
        #set riseArrival [get_attribute $port max_rise_delay]
        #set fallArrival [get_attribute $port max_fall_delay]
        #set riseArrival [get_attribute $port endpoint_output_delay_value]
        #set fallArrival [get_attribute $port endpoint_output_delay_value]
        set fanoutLoad [get_attribute $port fanout_load]
        # set minriseCeff [get_attribute $port cached_ceff_min_rise]
        # set maxriseCeff [get_attribute $port cached_ceff_max_rise]
        # set minfallCeff [get_attribute $port cached_ceff_min_fall]
        # set maxfallCeff [get_attribute $port cached_ceff_max_fall]
        #set maxCeff [get_attribute $port ceff_params_max]
        #set minCeff [get_attribute $port ceff_params_min]
        
        set riseSlack [get_attribute $port max_rise_slack]
        set fallSlack [get_attribute $port max_fall_slack]
        set riseTransition [get_attribute $port actual_rise_transition_max]
        set fallTransition [get_attribute $port actual_fall_transition_max]
        #puts $ofp "$portName $fanoutLoad $riseSlack $fallSlack $riseTransition $fallTransition"
        #puts $cofp "$pinName $fanoutLoad $minriseCeff $maxriseCeff $minfallCeff maxfallCeff"
        #puts $cofp "$pinName $fanoutLoad $minCeff $maxCeff"
        puts $ofp "$portName $riseArrival $fallArrival $riseSlack $fallSlack $riseTransition $fallTransition"
    }    

    close $ofp
    close $cofp
    return "success"
}

## If running HSTA_read_design directly, there will be issues
## HSTA_read_design 
#read_lib $::env(HSTA_TECH_LIB)
#lappend search_path $::env(HSTA_TECH_LIB)
puts "$search_path"
puts "$link_library"
puts "$symbol_library"
puts "$link_path"
puts "$TECH_FILE"


#read_db /home/lmin/hybrid-sta/TSMC_LIB_2013/NLDM/tcbn45gsbwp_120a/tcbn45gsbwptc.db
#list_libs
#read_verilog $::env(HSTA_BENCHMARK_DIR)/$::env(HSTA_BENCHMARK).v
#current_design $::env(HSTA_BENCHMARK)
#set_operating_conditions -analysis_type on_chip_variation  -library [get_libs *] 
#link_design $::env(HSTA_BENCHMARK)
#read_sdc $::env(HSTA_BENCHMARK_DIR)/$::env(HSTA_BENCHMARK).sdc
#read_parasitics $::env(HSTA_BENCHMARK_DIR)/$::env(HSTA_BENCHMARK).spef

# set design_read_status [HSTA_read_design]
# if { "err" == $design_read_status } {
#     puts "Error: Could not read design successfully"
#     exit
# }

# set run_timing_status [run_timing]
# if { "err" == $run_timing_status } {
#     puts "Error: Could not run timing successfully"
#     exit
# }

#set_case_analysis 1 blif_reset_net
check_timing
run_timing
report_timing

source pt2tmax.tcl
#source pt2tmax_old.tcl
#set runtime_ms [time {write_delay_paths -max_paths 100 -nworst 1 -IO -delay_type max $::env(HSTA_RPT_FILE)} 1]
#set runtime_ms [time {write_delay_paths -nworst 2 -max_paths 400 -slack 1.3 -IO -delay_type max $::env(HSTA_RPT_FILE)} 1]
set runtime_ms [time {write_delay_paths -nworst 40 -max_paths 600 -slack 10.0 -IO -delay_type max $::env(HSTA_RPT_FILE)} 1]
#set runtime_ms [time {write_delay_paths -nworst 40 -max_paths 600 -slack 10.0 -delay_type max $::env(HSTA_RPT_FILE)} 1]
set part1 [lindex [split $runtime_ms] 0]
set million 1000000.0
set runtime_s [expr {$part1 / $million}]
puts "Reporting critical path extraction time in seconds: $runtime_s"
puts ""
#report_port -verbose
#report_constraints -verbose

#exit